# -*-coding:utf-8 -*-
from huaweicloudsdkfrs.v2.region.frs_region import FrsRegion
from huaweicloudsdkfrs.v2 import *
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkivs.v2.region.ivs_region import IvsRegion
from huaweicloudsdkcore.exceptions import exceptions
from huaweicloudsdkivs.v2 import *

import json
import traceback
import datetime


# 验证环境变量是否配置
def check_configuration(context):
    region = context.getUserData('region')
    if not region:
        return 'region is not configured'

    ak = context.getAccessKey().strip()
    sk = context.getSecretKey().strip()
    if not ak or not sk:
        ak = context.getUserData('ak', '').strip()
        sk = context.getUserData('sk', '').strip()
        if not ak or not sk:
            return 'ak or sk is empty'


# 函数工作流调用入口
def handler(event, context):
    log = context.getLogger()
    result = check_configuration(context)
    if result is not None:
        return result

    records = event.get("queryStringParameters")
    if records is None:
        return 'Records is empty'
    processor = Processor(context)
    try:
        return processor.process(records)
    except:
        log.error("failed to process image, "
                  f"exception：{traceback.format_exc()}")


class Processor:
    def __init__(self, context=None):
        self.log = context.getLogger()
        self.frs_client = frs_client(context)
        self.ivs_client = ivs_client(context)
        self.video_url = None
        self.face_image = None
        self.actions = None
        self.uuid = None
        self.verification_name = None
        self.verification_id = None

    def process(self, record):
        # 解析record
        self.analysis_record(record)
        # 活体检测
        response_frs = self.live_detect()
        if not isinstance(response_frs, dict):
            response_frs = self.result_format_processing(response_frs)
            return response_frs
        else:
            # 获取活体检测服务相应的人脸图片信息
            video_result = response_frs["video-result"]
            if not video_result["alive"] or response_frs["warning-list"] != []:
                response_frs = self.result_format_processing("living body verification failed")
                return response_frs
            else:
                # 调用人证核身接口
                self.face_image = video_result["picture"]
                response_ivs = self.verification_identity()
                if not isinstance(response_ivs, dict):
                    response_ivs = self.result_format_processing(response_ivs)
                    return response_ivs
                # 调整响应结果结构
                else:
                    ivs_result = response_ivs["result"]
                    if ivs_result["resp_data"][0]["verification_code"] != 1000:
                        response_ivs = self.result_format_processing(
                            "Failed to verify the certificate of the applicant")
                        return response_ivs
                    else:
                        response_list = []
                        response_list.append(response_frs)
                        response_list.append(response_ivs)
                        response_info = self.result_format_processing(response_list)
                        return response_info

    def live_detect(self):
        client = self.frs_client
        # video_url 文件传输，获取活体检测结果
        if self.video_url and self.actions:
            try:
                request = DetectLiveByUrlRequest()
                request.body = LiveDetectUrlReq(
                    actions=self.actions,
                    video_url=self.video_url
                )
                response = client.detect_live_by_url(request)
                response_obj = response.to_json_object()
                response_dict = json.loads(json.dumps(response_obj))
                return response_dict
            except exceptions.ClientRequestException as e:
                self.log.error(f"failed to Face LiveDetect："
                               f"status_code：{e.status_code}, "
                               f"request_id:{e.request_id}, "
                               f"error_code:{e.error_code}. "
                               f"error_msg:{e.error_msg}")
                return "Failed to invoke the FRS service"
        else:
            return "video_url or actions not obtained"

    def verification_identity(self):
        client = self.ivs_client
        # 使用身份证号，姓名获取人证核身结果
        if self.verification_id and self.verification_name:
            try:
                request = DetectStandardByNameAndIdRequest()
                listStandardReqDataByNameAndIdReqDataIvsStandardByNameAndIdRequestBodyData = [
                    StandardReqDataByNameAndId(
                        verification_name=self.verification_name,
                        verification_id=self.verification_id,
                        face_image=self.face_image
                    )
                ]
                dataIvsStandardByNameAndIdRequestBodyData = IvsStandardByNameAndIdRequestBodyData(
                    req_data=listStandardReqDataByNameAndIdReqDataIvsStandardByNameAndIdRequestBodyData
                )
                metaMeta = Meta(
                    uuid=self.uuid
                )
                request.body = IvsStandardByNameAndIdRequestBody(
                    data=dataIvsStandardByNameAndIdRequestBodyData,
                    meta=metaMeta
                )
                response = client.detect_standard_by_name_and_id(request)
                response_obj = response.to_json_object()
                response_dict = json.loads(json.dumps(response_obj))
                return response_dict
            except exceptions.ClientRequestException as e:
                self.log.error(f"failed to verification_identity："
                               f"status_code：{e.status_code}, "
                               f"request_id:{e.request_id}, "
                               f"error_code:{e.error_code}. "
                               f"error_msg:{e.error_msg}")
                return "Failed to invoke the IVS service"
        else:
            return "verification_name or verification_id not obtained"

    # 获取记录信息
    def analysis_record(self, record):
        record = json.loads(json.dumps(record))
        video_url = record.get("video_url")
        self.video_url = video_url
        actions = record.get("actions")
        self.actions = actions
        self.uuid = datetime.datetime.now()
        verification_name = record.get("verification_name")
        self.verification_name = verification_name
        verification_id = record.get("verification_id")
        self.verification_id = verification_id


    def result_format_processing(self, response):
        info = str(response)
        info_dict = {
            "statusCode": 200,
            "isBase64Encoded": False,
            "headers": {},
            "body": info
        }
        return info_dict


def frs_client(context):
    ak = context.getAccessKey()
    sk = context.getSecretKey()
    credentials = BasicCredentials(ak, sk)
    client_frs = FrsClient.new_builder() \
        .with_credentials(credentials) \
        .with_region(FrsRegion.value_of(context.getUserData("region"))) \
        .build()
    return client_frs


def ivs_client(context):
    ak = context.getAccessKey()
    sk = context.getSecretKey()
    credentials = BasicCredentials(ak, sk)
    client_ivs = IvsClient.new_builder() \
        .with_credentials(credentials) \
        .with_region(IvsRegion.value_of(context.getUserData("region"))) \
        .build()
    return client_ivs